
#include <vector>

#include <base/resourcemanager.h>
#include <base/interface.h>
#include <base/d3d.h>

std::vector<Resource *> _resources;

long DestroyResources() {
  for(unsigned long i = 0; i < _resources.size(); i++) {
    if(_resources[i])
    {
      delete _resources[i];
      _resources[i] = NULL;
    }
  }

  return 0;
}

long LoadResourceFromFile(long type, std::string filename, Device * device) {
  //TODO: maybe make use of abandoned _resources elements?
  switch(type) {
    case RM_TEXTURE:
      _resources.push_back(new Texture(filename, device));
      break;
    case RM_SHADER:
      _resources.push_back(new Shader(filename, device));
      break;
  }

  //TODO: failure code
  return long(_resources.size()) - 1;
}

Resource * GetResource(long index) {
  return _resources[index];
}

Resource::Resource(unsigned long type) {
  _type = type;
}

DeviceResource::DeviceResource(Device * device, unsigned long type) : Resource(type){
  _device = device;
}

Texture::Texture(std::string filename, Device * device) : DeviceResource(device, RM_TEXTURE) {
  char temp[128];
  if(device->loadTexture(&_texture, filename.c_str())){
    sprintf_s(temp, "Could not load texture %s", filename.c_str());
    PrintConsoleLine(temp);
    _texture = NULL;
  }
}

Texture::~Texture() {
  if(_texture)
    _texture->Release();
}

LPDIRECT3DTEXTURE9 Texture::getTexture() {
  return _texture;
}

Shader::Shader(std::string filename, Device * device) : DeviceResource(device, RM_SHADER) {
  device->loadShader(&_shader, filename.c_str());
}

Shader::~Shader() {
  _shader->Release();
}

LPD3DXEFFECT Shader::getShader() {
  return _shader;
}

long Shader::addTechnique(std::string name) {
  D3DXHANDLE tech = _shader->GetTechniqueByName(name.c_str());
  _values.push_back(tech);
  return (long)_values.size() - 1;
}

void Shader::setTechnique(long tech) {
  _shader->SetTechnique(_values[tech]);
}
